﻿using System.Collections.Generic;

namespace Core.Experiment
{
    public class BlackBoard2 : Core.Component, IAwake, IUpdate
    {
        private class Item : IDispose
        {
            public float Timer;
            public string Key;
            public object Value;

            public void Dispose()
            {
                Timer = 0f;
                Key = null;
                Value = null;
            }
        }

        private readonly Dictionary<string, object> dict = new();
        private readonly Queue<Item> timers = new();

        public void Awake()
        {

        }

        public override void Dispose()
        {
            if (IsDisposed) return;
            base.Dispose();

            dict.Clear();
            timers.Clear();
        }

        public void Update()
        {
            var delta = UnityEngine.Time.deltaTime;

            int cnt = timers.Count;

            for (int i = 0; i < cnt; i++)
            {
                var item = timers.Dequeue();
                item.Timer -= delta;
                if (item.Timer > 0)
                {
                    timers.Enqueue(item);
                    continue;
                }
                ReferencePool.Recycle(item);
            }
        }

        private Item Get(float expiredTime, string key, bool expiredValue)
        {
            var item = ReferencePool.Acquire<Item>();
            item.Timer = expiredTime;
            item.Key = key;
            item.Value = expiredValue;
            return item;
        }

        public void SetValue(string key, bool value)
        {
            dict[key] = value;
        }

        public void SetValue(string key, bool value, float expiredTime, bool expiredValue)
        {
            dict[key] = value;

            timers.Enqueue(Get(expiredTime, key, expiredValue));
        }

        public void SetValue(string key, int value)
        {
            dict[key] = value;
        }

        public void SetValue(string key, int value, float expiredTime, bool expiredValue)
        {
            dict[key] = value;

            timers.Enqueue(Get(expiredTime, key, expiredValue));
        }

        public void SetValue(string key, float value)
        {
            dict[key] = value;
        }

        public void SetValue(string key, float value, float expiredTime, bool expiredValue)
        {
            dict[key] = value;

            timers.Enqueue(Get(expiredTime, key, expiredValue));
        }

        public void SetValue(string key, string value)
        {
            dict[key] = value;
        }

        public int GetInt(string key)
        {
            return (int)dict[key];
        }

        public float GetFloat(string key)
        {
            return (float)dict[key];
        }

        public bool GetBool(string key)
        {
            return (bool)dict[key];
        }

        public string GetString(string key)
        {
            return (string)dict[key];
        }

    }
}
